package com.yllt4cloud.ddauth.control;

import com.yllt4cloud.base.api.entity.SheBei;
import com.yllt4cloud.base.api.feign.RemoteSheBeiService;
import com.yllt4cloud.common.core.constant.CacheConstants;
import com.yllt4cloud.common.core.constant.SecurityConstants;
import com.yllt4cloud.common.core.constant.SystemConfigConstants;
import com.yllt4cloud.common.core.constant.enums.ErrorCodeEnum;
import com.yllt4cloud.common.core.exception.MessageException;
import com.yllt4cloud.common.core.util.ResultResp;
import com.yllt4cloud.common.ddbase.constant.*;
import com.yllt4cloud.common.ddbase.constant.entity.CryptEnum;
import com.yllt4cloud.common.ddbase.constant.entity.SessionEntity;
import com.yllt4cloud.common.ddbase.constant.entity.UserInfo;
import com.yllt4cloud.common.ddbase.domain.Clerk;
import com.yllt4cloud.common.ddbase.domain.Menu;
import com.yllt4cloud.common.ddbase.domain.SystemConfig;
import com.yllt4cloud.common.ddbase.domain.User;
import com.yllt4cloud.common.ddbase.param.LoginParam;
import com.yllt4cloud.common.ddbase.param.RequestParam;
import com.yllt4cloud.common.ddbase.result.GetMenusResult;
import com.yllt4cloud.common.ddbase.result.LoginResult;
import com.yllt4cloud.common.ddbase.util.Base64Utils;
import com.yllt4cloud.common.ddbase.util.CommonRedisUtil;
import com.yllt4cloud.common.ddbase.util.JsonUtil;
import com.yllt4cloud.common.ddbase.util.ValidateService;
import com.yllt4cloud.common.ddbase.util.crypto.CryptoManager;
import com.yllt4cloud.ddauth.service.IClerkService;
import com.yllt4cloud.ddauth.service.ILoginService;
import com.yllt4cloud.ddauth.service.IMenuService;
import com.yllt4cloud.ddauth.service.ISystemConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @description: 店端登录入口
 * @author: yaoxj
 * @create: 2019-12-09 11:28
 **/
@RestController
@Slf4j
public class LoginAct {

    @Autowired
    private ILoginService loginService;
    @Autowired
    private IClerkService clerkService;
    @Autowired
    private IMenuService menuService;
    @Autowired
    RemoteSheBeiService remoteSheBeiService;
    @Autowired
    private ISystemConfigService systemConfigService;
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CommonRedisUtil commonRedisUtil;

    @Value("${houTaiTuPianUrl}")
    private String houTaiTuPianUrl;

    @RequestMapping(value = "login")
    public ResultResp login(HttpServletRequest request, RequestParam requestParam) {
        LoginParam loginParam = JsonUtil.parseObject(requestParam.getData(), LoginParam.class);
        log.info("登录参数:"+JsonUtil.getShowJson(loginParam));
        //登陆参数验证
        ResultResp resultResp = ValidateService.validate(loginParam);
        if (resultResp != null) {
            log.error("请求参数有误");
            return resultResp;
        }

        Optional<User> loginUser = validateUserInfo(loginParam);
        Optional<Clerk> clerk = validateClerkInfo(loginUser.get().getClerkId());

        //获取模块
        if (gainMenuListByUserId(loginUser)) return ResultResp.fail("账号权限不足，无法登录", ErrorCode.NOT_BIND_CLERK);

        LoginResult loginResult = getLoginResult(loginUser, clerk);

        if (null != loginParam.getMac()) {
            Map<String,Object> sheBeiParam = new HashMap<>();
            ResultResp<SheBei> resultData=remoteSheBeiService.getSheBeiByMacAddr(loginParam.getMac(), SecurityConstants.FROM_IN);
            if (null != resultData) {
                SheBei sheBei=resultData.getResult();
                loginResult.setSheBeiId(sheBei.getId());
            }
        }

        SystemConfig systemConfig = new SystemConfig();
        systemConfig.setJianMing(SystemConfigConstants.SYS_CS_NAME);
        List<SystemConfig> list = systemConfigService.queryList(JsonUtil.parseMap(systemConfig));
        loginResult.setChangSuoName(list.get(0).getKeyValue());
        String  sysTime=commonRedisUtil.getSystemConfigValue(SystemConfigConstants.SYSTEM_TIME);

        try {
            loginResult.setWorkDate(new SimpleDateFormat("yyyy-MM-dd").parse(sysTime));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //会员卡类型(可视还是磁条)
        systemConfig.setJianMing(SystemConfigConstants.SYS_CARD_TYPE);
        List<SystemConfig> memberCardTypeList = systemConfigService.queryList(JsonUtil.parseMap(systemConfig));
        loginResult.setMemberCardType(Integer.valueOf(memberCardTypeList.get(0).getKeyValue()));

        systemConfig = systemConfigService.selectByPrimaryJianMing(SystemConfigConstants.DD_FOOD_TIAOJIA);
        loginResult.setCanTiaoJia(systemConfig == null ? 0 :Integer.parseInt(systemConfig.getKeyValue()));

        redisTemplate.opsForHash().put(CacheConstants.DD_IP_SESSION_CONTAINER, request.getRemoteAddr(), loginResult.getSession());

//      -------------增加是否供应链版本 2018-09-11 JieLin -------------------------

        String  isGongYingLian=commonRedisUtil.getSystemConfigValue(SystemConfigConstants.IS_SUPPLY_CHAIN_VERSION);
        String  sysCsIncon= commonRedisUtil.getSystemConfigValue(SystemConfigConstants.SYS_CS_ICON);
        loginResult.setIs_gongyinglian(isGongYingLian);

//        String logoUrl=houTaiTuPianUrl +SystemConfigContainer.instance().getSysCsIcon();
        String logoUrl=houTaiTuPianUrl +sysCsIncon;
        //设置场所图标
        loginResult.setLogoIcon(logoUrl);
        log.info("场所图标地址"+logoUrl);
        return ResultResp.success(loginResult);
    }

    private LoginResult getLoginResult(Optional<User> loginUser, Optional<Clerk> clerk) {
        String clerkName=clerk.get().getName();
        Integer clerkId=clerk.get().getId();
        String token = UUID.randomUUID().toString();
        //用户id，服务端找对应的session内容用
        //session 中存员工信息
        String sessionKey =  StringUtils.isEmpty(clerkName) ? clerk.get().getClerkCardNum() : clerkName;

        //秘钥，给客户端加密用
        String encryptKey = UUID.randomUUID().toString();
        encryptKey = encryptKey.replace("-", "").substring(0, 16);
        Map<String, String> content = new HashMap<String, String>();
        content.put("userName", clerkName);
        content.put("token", token);
        content.put("user", sessionKey);

        SessionEntity sessionEntity = new SessionEntity();
        sessionEntity.setToken(token);
        sessionEntity.setEncryptKey(encryptKey);
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(loginUser.get().getId());  //这里存管理用户(user)  id
        userInfo.setUserName(clerkName);  //取员工登入名
        //设置登入用户对应的员工id
        userInfo.setClerkId(clerkId);
        sessionEntity.setUserInfo(userInfo);

        String returnSession = Base64Utils.encode(JsonUtil.toJson(content).getBytes());
        commonRedisUtil.addSessionEntity(returnSession,sessionEntity);

        log.info("returnSession" + returnSession);
        LoginResult loginResult = new LoginResult();
        loginResult.setUserId(String.valueOf(loginUser.get().getId())); //这里存管理用户(user)  id
        loginResult.setKey(encryptKey);
        loginResult.setSession(returnSession);
        loginResult.setUserName(clerkName); //取员工登入名
        //设置登入用户对应的员工id
        loginResult.setClerkId(clerkId);
        return loginResult;
    }

    private boolean gainMenuListByUserId(Optional<User> loginUser) {
        Map<String, Object> paramMap=new HashMap<String, Object>();
        paramMap.put("userId", loginUser.get().getId());
        paramMap.put("menuType", MenuConstants.Menu_Type_DIANDUAN);
        paramMap.put("parentFlag", AuthorityConstants.PARENTFLAG_MODULE);
        paramMap.put("orderBy", "PaiXuHao");
        paramMap.put("sortBy", "asc");
        List<Menu> listModel=menuService.queryMenuByParam(paramMap);
        if(listModel==null || listModel.size()==0){
            log.error("账号配置的角色，没有菜单数据");
            return true;
        }
        return false;
    }

    //验证用户对于的职员信息
    private Optional<Clerk> validateClerkInfo(Integer clerkId) {
        Optional<Clerk> clerk=Optional.ofNullable(clerkService.selectByPrimaryKey(clerkId));
        clerk.orElseThrow(() -> new MessageException(ErrorCodeEnum.NOT_HAVE_CLERK));
        clerk.filter(u -> u.getStatus()==ClerkConstants.CLERK_STATUS_ENABLE).orElseThrow(() ->
                new MessageException("账号绑定的员工异常", ErrorCode.DATA_STATUS_ERROR));
        return clerk;
    }

    //验证用户的基本信息
    private Optional<User> validateUserInfo(LoginParam loginParam)  {
        Boolean flag=loginService.validateName(loginParam.getUserName());
        if(!flag){
            throw  new MessageException(ErrorCodeEnum.DATA_DOESNOT_EXIST);
        }
        User user=new User();
        user.setLoginName(loginParam.getUserName());
        user.setPassword(CryptoManager.getInstance().getCrypto(CryptEnum.MD5).encrypt(loginParam.getPassword(), ""));

        Optional<User> loginUser=Optional.ofNullable(loginService.login(user));
        loginUser.orElseThrow(() -> new MessageException(ErrorCodeEnum.USERNAME_OR_PASSWORD_ERROR));
        loginUser.filter(u -> UserConstants.USER_STATUS_ENABLE==u.getStatus()).orElseThrow(() -> new MessageException(ErrorCodeEnum.DATA_STATUS_ERROR));
        loginUser.filter(u -> u.getClerkId()!=null).orElseThrow(() -> new MessageException(ErrorCodeEnum.NOT_BIND_CLERK));
        return loginUser;
    }





    /**
     * 获取登入的用户菜单
     * @param request
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "getMenus")
    public ResultResp<GetMenusResult> getMenus(HttpServletRequest request) {
        String sessionKey=request.getParameter("session");
        SessionEntity sessionEntity = (SessionEntity)commonRedisUtil.getSessionEntity(sessionKey);
        Integer userId=null;
        GetMenusResult menuInfo=null;
        if(sessionEntity!=null){
             userId=sessionEntity.getUserInfo().getUserId();
        }
//        Integer userId = ApplicationContext.CTX.currentUserId();
        //获取用户店端的菜单列表
        if(userId!=null){
             menuInfo = menuService.queryModule(userId, MenuConstants.Menu_Type_DIANDUAN);
        }
        return ResultResp.success(menuInfo);
    }

}
